# 数据可视化层
import json
import os

import pandas as pd
from flask import Flask
from flask_cors import CORS
from pyecharts import options as opts
from pyecharts.charts import Grid, Bar, Map, Pie
from pyecharts.charts import Line, Timeline
from pyecharts.commons.utils import JsCode
from pyecharts.globals import ThemeType

app = Flask(__name__)
CORS(app)  # 启用CORS


class pyeCharts:
    def __init__(self):
        pass

    # 给每个城市绘制一个 10 年来指定数据变化折线图
    @staticmethod
    def drawLineForCommon(city_common_data, filename):
        city_ = ['北京市', '上海市', '广东省', '湖北省', '江苏省', '江西省']
        l = Line(
            init_opts=opts.InitOpts(
                width="1600px",
                height="900px",
                page_title=f"{filename}变化折线图",
                renderer="canvas",
                theme="light",

            )
        )
        x_data = city_common_data.columns.tolist()
        l.add_xaxis(x_data)
        for city_index in city_common_data.index:
            if city_index in city_:
                y_data = city_common_data.loc[city_index].tolist()
                l.add_yaxis(city_index, y_data, linestyle_opts=opts.LineStyleOpts(width=2))
        l.set_global_opts(
            title_opts=opts.TitleOpts(title=f"{filename}", pos_left="center"),
            tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b} : {c}"),
            legend_opts=opts.LegendOpts(pos_left="left"),
            xaxis_opts=opts.AxisOpts(type_="category", name="x"),
            yaxis_opts=opts.AxisOpts(
                type_="log",
                name="y",
                splitline_opts=opts.SplitLineOpts(is_show=True),
                is_scale=True,
                # 设置刻度数量，这里是一个示例值，你可以根据需要调整
                split_number=10,
            ),
        )

        if not os.path.exists("Echarts"):
            os.mkdir("Echarts")

        url = f"Echarts\\{filename}折线图.html"

        l.render(url)

        return l

    # 将数据转换成指定的格式
    @staticmethod
    def parsel_data(city_development_data):
        # 将数据转换成所需的格式
        index = list(city_development_data.index)
        # 年份列表
        year_list = ['2014', '2015', '2016', '2017', '2018', '2019', '2020', '2021', '2022']
        data = []
        for year in year_list:
            data_item = {'time': int(year), 'data': []}
            development_data_list = city_development_data[year].tolist()  # 获取指定年份的一列
            for i in range(len(index)):
                data_item_item = {'name': index[i]}
                value = [development_data_list[i], 0.3, index[i]]
                data_item_item['value'] = value
                data_item['data'].append(data_item_item)
            data.append(data_item)
        return data

    # 绘制发展指数地图
    @staticmethod
    def drawMapForDevelopment(city_development_data, filename):

        timeline = Timeline(
            init_opts=opts.InitOpts(width="1600px", height="900px", theme=ThemeType.DARK)
        )

        time_list = [2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022]
        for y in time_list:
            g = pyeCharts().get_year_chart(y, city_development_data, filename)
            timeline.add(g, time_point=str(y))

        timeline.add_schema(
            orient="vertical",
            is_auto_play=True,
            is_inverse=True,
            play_interval=5000,
            pos_left="null",
            pos_right="5",
            pos_top="20",
            pos_bottom="20",
            width="50",
            label_opts=opts.LabelOpts(is_show=True, color="#fff"),
        )

        timeline.render(f"Echarts\\{filename}.html")
        return timeline

    # 辅助方法
    @staticmethod
    def get_year_chart(year, city_development_data, filename):
        data = pyeCharts().parsel_data(city_development_data)
        map_data = []
        for d in data:
            if d["time"] == year:
                temp_list = []
                for x in d["data"]:
                    temp_list.append([x["name"], x["value"]])
                map_data = temp_list
                break  # 只处理第一个匹配的年份

        data_list = []
        for t in [d[1][0] for d in map_data]:
            data_list.append(float(t))
        min_data, max_data = (
            min(data_list),
            max(data_list),
        )
        map_chart = (
            Map()
            .add(
                series_name="",
                data_pair=map_data,
                label_opts=opts.LabelOpts(is_show=True),
                is_map_symbol_show=False,
                itemstyle_opts={
                    "normal": {"areaColor": "#323c48", "borderColor": "#404a59"},
                    "emphasis": {
                        "label": {"show": Timeline},
                        "areaColor": "rgba(255,255,255, 0.5)",
                    },
                },
            )
            .set_global_opts(
                title_opts=opts.TitleOpts(
                    title=f"{filename}",
                    pos_left="center",
                    pos_top="top",
                    title_textstyle_opts=opts.TextStyleOpts(
                        font_size=25, color="rgba(255,255,255, 0.9)"
                    ),
                ),
                tooltip_opts=opts.TooltipOpts(
                    is_show=True,
                    formatter=JsCode(
                        """function(params) {
                        if ('value' in params.data) {
                            return params.data.value[2] + ': ' + params.data.value[0];
                        }
                    }"""
                    ),
                ),
                visualmap_opts=opts.VisualMapOpts(
                    is_calculable=True,
                    dimension=0,
                    pos_left="10",
                    pos_top="center",
                    range_text=["High", "Low"],
                    range_color=["lightskyblue", "yellow", "orangered"],
                    textstyle_opts=opts.TextStyleOpts(color="#ddd"),
                    min_=min_data,
                    max_=max_data,
                ),
            )
        )

        grid_chart = (
            Grid(init_opts=opts.InitOpts(width='1600px', height='900px'))
            .add(map_chart, grid_opts=opts.GridOpts(pos_left="50%", pos_right="10%", pos_top="10%", pos_bottom="10%"),
                 is_control_axis_index=True)
        )
        return grid_chart

    # 生成各地区发展指数条形图
    @staticmethod
    def drawBarForDevelopment(city_development_data: object, filename: object) -> object:
        global c
        year_list = city_development_data.columns.tolist()[0:1]  # 获取年份列表
        index = city_development_data.index.tolist()  # 获取横坐标
        for year in year_list:
            filename_ = f"Echarts\\{year}年发展指数条形图.html"
            data_dict = {}
            x_data = index
            y_data = city_development_data[year].tolist()
            for i in range(len(index)):
                data_dict[index[i]] = y_data[i]
            data_dict = dict(sorted(data_dict.items(), key=lambda x: x[1], reverse=True))
            x_data = list(data_dict.keys())
            y_data = list(data_dict.values())
            c = (
                Bar(
                    init_opts=opts.InitOpts(width="1600px", height="900px", theme=ThemeType.DARK)
                )
                .add_xaxis(x_data)
                .add_yaxis("发展指数", y_data, stack="stack1")
                .set_series_opts(label_opts=opts.LabelOpts(is_show=False))
                .set_global_opts(
                    title_opts=opts.TitleOpts(title=f"各地区{year}发展指数"),
                    xaxis_opts=opts.AxisOpts(
                        axislabel_opts=opts.LabelOpts(rotate=45, interval=0)  # 设置标签旋转45度，并显示所有标签
                    )
                )
            )
            c.render(filename)
            return c

    # 绘制各地区GDP线性回归预测图
    @staticmethod
    def drawLineForFutureGDP(future_data):
        city_ = ['北京市', '上海市']
        l = Line(
            init_opts=opts.InitOpts(
                width="1600px",
                height="900px",
                page_title="未来5年GDP线性回归预测图",
                renderer="canvas",
                theme="light",
            )
        )
        x_data = future_data.columns.tolist()
        l.add_xaxis(x_data)
        for city_index in future_data.index:
            if city_index in city_:
                y_data = future_data.loc[city_index].tolist()
                l.add_yaxis(city_index, y_data, linestyle_opts=opts.LineStyleOpts(width=2))
        l.set_global_opts(
            title_opts=opts.TitleOpts(title="未来5年GDP线性回归预测图.html", pos_left="center"),
            tooltip_opts=opts.TooltipOpts(trigger="item", formatter="{a} <br/>{b} : {c}"),
            legend_opts=opts.LegendOpts(pos_left="left"),
            xaxis_opts=opts.AxisOpts(type_="category", name="x"),
            yaxis_opts=opts.AxisOpts(
                type_="log",
                name="y",
                splitline_opts=opts.SplitLineOpts(is_show=True),
                is_scale=True,
                # 设置刻度数量，这里是一个示例值，你可以根据需要调整
                split_number=10,
            ),
        )

        if not os.path.exists("Echarts"):
            os.mkdir("Echarts")

        url = 'Echarts\\未来5年GDP线性回归预测图.html'

        l.render(url)
